package org.swim.remote.manager;

import java.util.List;

import javax.ejb.Remote;
import javax.naming.NamingException;

import net.sf.json.JSONObject;

import org.hibernate.exception.ConstraintViolationException;
import org.swim.remote.exceptions.AbilityException;
import org.swim.remote.exceptions.SwimException;
import org.swim.remote.exceptions.TokenException;
import org.swim.remote.exceptions.UserException;
import org.swim.remote.entities.INotification;
import org.swim.remote.entities.IUser;

@Remote
public interface UserManagerRemote extends SwimEntityManager<IUser> {

	/**
	 * { name: "", surname: "", email: "", password: "" }
	 * 
	 * @param object
	 * @return
	 * @throws ConstraintViolationException
	 * @throws UserException
	 */
	public abstract String signUp(JSONObject object)
			throws ConstraintViolationException, UserException;

	/**
	 * { email: "" password: "" }
	 * 
	 * @param object
	 * @return
	 * @throws ConstraintViolationException
	 * @throws UserException
	 */
	public abstract String signIn(JSONObject object)
			throws ConstraintViolationException, UserException;

	/**
	 * { token: "" }
	 * 
	 * @param object
	 * @throws UserException
	 * @throws TokenException
	 */
	public abstract void signOut(JSONObject object) throws UserException,
			TokenException;

	/**
	 * "...."
	 * 
	 * @param token
	 * @return
	 * @throws TokenException
	 * @throws SwimException
	 */
	public abstract IUser getTokenOwner(String token) throws TokenException,
			SwimException;

	/**
	 * { token: "..." ability: {name:"..."} }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws AbilityException
	 * @throws NamingException
	 * @throws UserException
	 * @throws SwimException
	 */
	public abstract IUser addAbility(JSONObject object) throws TokenException,
			AbilityException, NamingException, UserException, SwimException;

	/**
	 * { token: "..." ability: {name:"..."} }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws AbilityException
	 * @throws NamingException
	 * @throws UserException
	 * @throws SwimException
	 */
	public abstract IUser removeAbility(JSONObject object)
			throws TokenException, AbilityException, NamingException,
			UserException, SwimException;

	/**
	 * { token: "..." user: { name:"..." surname: "", email: "", password: "" }
	 * }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws UserException
	 * @throws SwimException
	 */
	public abstract IUser updateUser(JSONObject object) throws TokenException,
			UserException, SwimException;

	/**
	 * { token: "..." password: "..." }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws UserException
	 * @throws SwimException
	 */
	public abstract void removeAccount(JSONObject object)
			throws TokenException, UserException, SwimException;

	/**
	 * { token: "..." abilties:["","",...] }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws NamingException
	 * @throws AbilityException
	 */
	public abstract List<IUser> findNoFriendsByAbility(JSONObject object)
			throws TokenException, AbilityException, NamingException;

	/**
	 * { token: "..." query:"NAME_OF_USER" }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 */
	public abstract List<IUser> findNoFriendsByName(JSONObject object)
			throws TokenException;

	/**
	 * { token: "..." abilties:["","",...] }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws NamingException
	 * @throws AbilityException
	 */
	public abstract List<IUser> findFriendsByAbility(JSONObject object)
			throws TokenException, AbilityException, NamingException;

	/**
	 * { token: "..." query:"NAME_OF_USER" }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 */
	public abstract List<IUser> findFriendsByName(JSONObject object)
			throws TokenException;

	/**
	 * { search-query: {name:"..."} }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws AbilityException
	 * @throws NamingException
	 * @throws UserException
	 */
	public abstract List<IUser> findUsers(JSONObject query);

	/**
	 * { abilties:["","",...] }
	 * 
	 * @param object
	 * @return
	 * @throws AbilityException
	 * @throws NamingException
	 */
	public abstract List<IUser> findUsersByAbilities(JSONObject query)
			throws AbilityException, NamingException;

//	/**
//	 * { token: "..." }
//	 * 
//	 * @param object
//	 * @return
//	 * @throws TokenException
//	 */
//	public abstract List<IUser> findFriends(JSONObject object)
//			throws TokenException;

	/**
	 * { token: "..." }
	 * 
	 * @param object
	 * @return
	 * @throws TokenException
	 * @throws UserException
	 */
	public abstract List<INotification> getLastNotification(JSONObject object) throws TokenException, UserException;

	/**
	 * { name: "" password: "" }
	 * 
	 * @param object
	 * @return
	 * @throws UserException
	 */
	public String administratorSignIn(JSONObject object) throws UserException;

	/**
	 * { token: "..." }
	 * 
	 * @param object
	 * @return
	 * @throws UserException
	 */
	public void administratorSignOut(JSONObject object) throws TokenException;
}
